using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using FireStarter.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Util;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    /// <summary>
    /// Provides a place to write custom tests for DMObjectIdentity objects.
    /// This file is only written once and can be changed.  The Def file
    /// attached to this as a dependent is rewritten with each regeneration
    /// and contains the standard tests for DMObjectIdentity.
    /// Regenerate this test project whenever there have been changes to the
    /// business objects.
    /// If tests are failing due to a unique setup in your application,
    /// you can either override the Create methods in TestUtils, or you
    /// can add the test to the ignore list below and reimplement it here.
    /// </summary>
    public partial class TestDMObjectIdentity
    {
        // ReSharper disable InconsistentNaming
        [SetUp]
        public override void SetupTest()
        {
            //Runs every time that any testmethod is executed
            base.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            base.SetupFixture();
        }

        [TearDown]
        public override void TearDownTest()
        {
            //runs every time any testmethod is complete
            base.TearDownTest();
        }
        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmObjectIdentity.Class);
            //---------------Execute Test ----------------------
            string actualToString = dmObjectIdentity.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dmObjectIdentity.Class.ClassNameBO + " = Identity", actualToString);
        }

        [Test]
        public void Test_ToString_ClassNameBOIsNull()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity_NoDMClass();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmObjectIdentity.Class);
            //---------------Execute Test ----------------------
            string actualToString = dmObjectIdentity.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(StringUtilities.GuidToUpper(dmObjectIdentity.ObjectIdentityID.GetValueOrDefault()), actualToString);
        }
        [Test]
        public void Test_ToString_LookupListIsNull_IDIsNull()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            dmObjectIdentity.Class = null;
            dmObjectIdentity.ObjectIdentityID = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(dmObjectIdentity.Class);
            Assert.IsNull(dmObjectIdentity.ObjectIdentityID);
            //---------------Execute Test ----------------------
            string actualToString = dmObjectIdentity.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual("-unnamed DMObjectIdentity-", actualToString);
        }
        [Test]
        public void Test_InsertNewObjectIdentityInfo_WhenIsStringProp_WhenIsObjectIDTrue_ShouldChangeObjectIDtoFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfo();
            dmObjectIdentity.IsObjectID = true;
            dmObjectIdentity.Properties[0].PropertyTypeString = "System.String";
            //---------------Assert Precondition----------------
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual("System.Guid", dmObjectIdentity.Properties[0].PropertyTypeString); 
            Assert.IsTrue(dmObjectIdentity.IsObjectID.Value);
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();
            
            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }
        
        [Test]
        public void Test_InsertNewObjectIdentityInfo_OneGuidProp_WhenIsObjectIDTrue_ShouldLeaveIsObjectIDTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfo();
            DMPropertyType dmPropertyType = TestUtilsShared.CreateUnsavedValidPropertyTypeInfo();
            dmPropertyType.AssemblyName = "System";
            dmPropertyType.PropertyTypeName = "Guid";
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = dmPropertyType;
            //---------------Assert Precondition----------------
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual("System.Guid", dmProperty);
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }        
        [Test]
        public void Test_InsertNewObjectIdentityInfo_OneGuidProp_WhenIsObjectIDFalse_ShouldChangeIsObjectIDTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfo();
            DMPropertyType dmPropertyType = TestUtilsShared.CreateUnsavedValidPropertyTypeInfo();
            dmPropertyType.AssemblyName = "System";
            dmPropertyType.PropertyTypeName = "Guid";
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = dmPropertyType;
            dmObjectIdentity.IsObjectID = false;
            //---------------Assert Precondition----------------
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual("System.Guid", dmProperty);
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }     
        [Test]
        public void Test_UpdateObjectIdentityInfo_OneGuidProp_WhenIsObjectIDFalse_ShouldChangeIsObjectIDTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfo();
            DMPropertyType dmPropertyType = TestUtilsShared.CreateUnsavedValidPropertyTypeInfo();
            dmPropertyType.AssemblyName = "System";
            dmPropertyType.PropertyTypeName = "Guid";
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = dmPropertyType;
            dmObjectIdentity.Save();
            dmObjectIdentity.IsObjectID = false;
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual("System.Guid", dmProperty);
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }     

        [Test]
        public void Test_UpdateObjectIdentityInfo_TwoGuidProp_WhenIsObjectIDTrue_ShouldChangeIsObjectIDFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfoWithTwoProps();

            dmObjectIdentity.Save();
            dmObjectIdentity.IsObjectID = true;
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmObjectIdentity.Properties.Count);
            Assert.AreEqual("System.Guid", dmObjectIdentity.Properties[0].PropertyTypeString);
            Assert.AreEqual("System.Guid", dmObjectIdentity.Properties[1].PropertyTypeString);
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }   

        [Test]
        public void Test_UpdateObjectIdentityInfo_OneStringProp_WhenIsObjectIDTrue_ShouldChangeIsObjectIDFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateUnsavedValidObjectIdentityInfo();
            DMPropertyType dmPropertyType = TestUtilsShared.CreateUnsavedValidPropertyTypeInfo();
            dmPropertyType.AssemblyName = "System";
            dmPropertyType.PropertyTypeName = "String";
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = dmPropertyType;
            dmObjectIdentity.Save();
            dmObjectIdentity.IsObjectID = true;
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual("System.Guid", dmProperty);
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }

        [Test]
        public void Test_InsertNewObjectIdentityInfo_Invalid()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();

            //---------------Assert Precondition----------------
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);

            //---------------Execute Test ----------------------
            try
            {
                dmObjectIdentity.Save();
                Assert.Fail("expected Err");
            }
            //---------------Test Result -----------------------
            catch (BusObjectInAnInvalidStateException ex)
            {
                StringAssert.Contains("Class ID' is a compulsory field and has no value", ex.Message);
            }
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);
        }

        [Test]
        public void Test_DeleteObjectIdentityInfo()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateSavedObjectIdentityInfo();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            string message;
            Assert.IsTrue(dmObjectIdentity.IsDeletable(out message));

            //---------------Execute Test ----------------------
            dmObjectIdentity.MarkForDelete();
            dmObjectIdentity.Save();

            //---------------Test Result -----------------------  
            Assert.IsTrue(dmObjectIdentity.Status.IsNew);
            Assert.IsTrue(dmObjectIdentity.Status.IsDeleted);
        }

        [Test]
        public void Test_UpdateObjectIdentityInfo()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateSavedObjectIdentityInfo();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            string message;
            Assert.IsTrue(dmObjectIdentity.IsEditable(out message));

            //---------------Execute Test ----------------------
            dmObjectIdentity.IsObjectID = false;
            dmObjectIdentity.Generated = true;

            dmObjectIdentity.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
        }

        [Test]
        public void Test_LoadObjectIdentityInfo()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = TestUtilsShared.CreateSavedObjectIdentityInfo();
            BusinessObjectManager.Instance.ClearLoadedObjects();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMObjectIdentity loadedDMObjectIdentity = Broker.GetBusinessObject<DMObjectIdentity>(dmObjectIdentity.ID);

            //---------------Test Result -----------------------  
            Assert.IsFalse(loadedDMObjectIdentity.Status.IsNew);
            Assert.AreEqual(loadedDMObjectIdentity.ID, dmObjectIdentity.ID);
            //TODO: When not using memory db Assert.AreNotSame(loadedDMObjectIdentity, businessObjectInfo);
        }

        [Test]
        public void Test_SetPrimaryKeyToBOProp_AddsPropToPrimaryKey()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);

            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity
                    {
                        IsObjectID = false,
                        Class = (DMClass) dmProperty.Class
                    };
            //---------------Assert Precondition----------------
            Assert.IsNull(dmProperty.ObjectIdentity);
            //---------------Execute Test ----------------------
            dmProperty.ObjectIdentity = dmObjectIdentity;
            //---------------Test Result -----------------------
            IBOProp prop = dmProperty.Props["ObjectIdentityID"];
            Assert.AreEqual(dmObjectIdentity.ObjectIdentityID, dmProperty.ObjectIdentityID);
            Assert.AreSame(dmObjectIdentity, dmProperty.ObjectIdentity);
            Assert.IsNull(prop.PersistedPropertyValue);
            Assert.AreEqual(1, dmObjectIdentity.Properties.CreatedBusinessObjects.Count);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
        }

        [Test]
        public void Test_AddProperty_SetsPropertyToCompulsory_AndWriteNew()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);

            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity
                    {
                        IsObjectID = false,
                        Class = (DMClass) dmProperty.Class
                    };
            //---------------Assert Precondition----------------
            Assert.IsNull(dmProperty.ObjectIdentity);
            Assert.IsFalse(dmProperty.Compulsory.GetValueOrDefault());
            Assert.AreEqual(PropReadWriteRule.ReadWrite, dmProperty.ReadWriteRule);
            //---------------Execute Test ----------------------
            dmProperty.ObjectIdentity = dmObjectIdentity;
            //---------------Test Result -----------------------
            Assert.IsTrue(dmProperty.Compulsory.GetValueOrDefault());
            Assert.AreEqual(PropReadWriteRule.WriteNew, dmProperty.ReadWriteRule);
        }

        [Test]
        public void Test_AddProperty_WhenAutoIncrementing_SetsPropertyToWriteNewOnly()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);
            dmProperty.AutoIncrementing = true;
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity
                    {
                        IsObjectID = false,
                        Class = (DMClass) dmProperty.Class
                    };
            //---------------Assert Precondition----------------
            Assert.IsNull(dmProperty.ObjectIdentity);
            Assert.IsFalse(dmProperty.Compulsory.GetValueOrDefault());
            Assert.IsTrue(dmProperty.AutoIncrementing.GetValueOrDefault());
            Assert.AreEqual(PropReadWriteRule.ReadWrite, dmProperty.ReadWriteRule);
            //---------------Execute Test ----------------------
            dmProperty.ObjectIdentity = dmObjectIdentity;
            //---------------Test Result -----------------------
            Assert.IsFalse(dmProperty.Compulsory.GetValueOrDefault());
            Assert.AreEqual(PropReadWriteRule.WriteNew, dmProperty.ReadWriteRule);
        }

        [Test]
        public void Test_SavePrimaryKeySavesAssociatedBOPropertiers()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);

            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity
                    {
                        IsObjectID = false,
                        Class = (DMClass) dmProperty.Class
                    };
            dmProperty.ObjectIdentity = dmObjectIdentity;
            IBOProp prop = dmProperty.Props["ObjectIdentityID"];

            //---------------Assert Precondition----------------
            Assert.AreSame(dmObjectIdentity, dmProperty.ObjectIdentity);
            Assert.IsNull(prop.PersistedPropertyValue);
            Assert.AreEqual(1, dmObjectIdentity.Properties.CreatedBusinessObjects.Count);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();
            //---------------Test Result -----------------------
            Assert.AreEqual(dmObjectIdentity.ObjectIdentityID, prop.PersistedPropertyValue);
        }

        [Test]
        public void Test_PropertiesReturnsSaved()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);
            
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity
                    {
                        IsObjectID = false,
                        Class = (DMClass) dmProperty.Class
                    };
            dmProperty.ObjectIdentity = dmObjectIdentity;
            dmObjectIdentity.Save();
            BusinessObjectManager.Instance.ClearLoadedObjects();
            //---------------Assert Precondition----------------
            Assert.IsFalse(dmProperty.Status.IsNew);
            //Assert.IsFalse(dmProperty.Status.IsDirty);  Why is associative relationship not saving the entire object - the status is still dirty?
            Assert.AreEqual(1, savedBo.Properties.Count);
            //---------------Execute Test ----------------------
            BusinessObjectManager.Instance.ClearLoadedObjects();
            int count = dmObjectIdentity.Properties.Count;
            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            Assert.AreEqual(1, count);

        }

        [Test]
        public void Test_GetProperties()
        {
            //---------------Set up test pack-------------------
            DMClass savedBo = TestUtilsShared.CreateUnsavedValidDMClass();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(savedBo);
            DMObjectIdentity dmObjectIdentity = CreateSavedObjectIdentityInfo(dmProperty);
            BusinessObjectManager.Instance.ClearLoadedObjects();
            //---------------Assert Precondition----------------
            Assert.IsFalse(dmObjectIdentity.Status.IsNew);
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            DMProperty loadedDMProperty = dmObjectIdentity.Properties[0];
            //---------------Test Result -----------------------
            Assert.AreEqual(dmProperty.ID, loadedDMProperty.ID);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_TrueIfAreSame()
        {
            //---------------Set up test pack-------------------
            DMClass bo = TestUtilsShared.CreateSavedDMClass();
            TestUtilsShared.CreateSavedDMProperty(bo);
            DMProperty propertyInfo2 = TestUtilsShared.CreateSavedDMProperty(bo);
            TestUtilsShared.CreateSavedDMProperty(bo);

            List<DMProperty> selectedProperties = new List<DMProperty> { propertyInfo2 };
            bo.SetObjectIdentity(selectedProperties);
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreSame(propertyInfo2, dmObjectIdentity.Properties[0]);
            Assert.IsTrue(propertyInfo2.IsPartOfObjectIdentity);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(selectedProperties);
            //---------------Test Result -----------------------
            Assert.IsTrue(areEqual);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_FalseIfNull()
        {
            //---------------Set up test pack-------------------
            DMProperty propertyInfo2;
            List<DMProperty> selectedProperties;
            DMClass bo = CreateBOWithIDThatHasOneProperty(out propertyInfo2, out selectedProperties);
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreSame(propertyInfo2, dmObjectIdentity.Properties[0]);
            Assert.IsTrue(propertyInfo2.IsPartOfObjectIdentity);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(null);
            //---------------Test Result -----------------------
            Assert.IsFalse(areEqual);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_TrueIfObjectIDHasNoPropertiesAndNull()
        {
            //---------------Set up test pack-------------------
            DMClass bo = TestUtilsShared.CreateSavedDMClass();
            TestUtilsShared.CreateSavedDMProperty(bo);
            TestUtilsShared.CreateSavedDMProperty(bo);

            List<DMProperty> selectedProperties = new List<DMProperty> ();
            bo.SetObjectIdentity(selectedProperties);
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(0, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(null);
            //---------------Test Result -----------------------
            Assert.IsTrue(areEqual);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_SameList_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            DMProperty propertyInfo2;
            List<DMProperty> selectedProperties;
            DMClass bo = CreateBOWithIDThatHasOneProperty(out propertyInfo2,out selectedProperties );
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreSame(propertyInfo2, dmObjectIdentity.Properties[0]);
            Assert.IsTrue(propertyInfo2.IsPartOfObjectIdentity);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(selectedProperties);
            //---------------Test Result -----------------------
            Assert.IsTrue(areEqual);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_NewListEmpty_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            DMProperty propertyInfo2;
            List<DMProperty> selectedProperties;
            DMClass bo = CreateBOWithIDThatHasOneProperty(out propertyInfo2,out selectedProperties );
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreSame(propertyInfo2, dmObjectIdentity.Properties[0]);
            Assert.IsTrue(propertyInfo2.IsPartOfObjectIdentity);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(new List<DMProperty>());
            //---------------Test Result -----------------------
            Assert.IsFalse(areEqual);
        }

        [Test]
        public void Test_ArePropertiesSameAsList_NewListSameNoItems_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            DMProperty propertyInfo2;
            List<DMProperty> selectedProperties;
            DMClass bo = CreateBOWithIDThatHasOneProperty(out propertyInfo2,out selectedProperties );
            //-------------Assert Preconditions -------------
            DMObjectIdentity dmObjectIdentity = bo.ObjectIdentity;
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreSame(propertyInfo2, dmObjectIdentity.Properties[0]);
            Assert.IsTrue(propertyInfo2.IsPartOfObjectIdentity);
            //---------------Execute Test ----------------------
            bool areEqual = dmObjectIdentity.ArePropertiesEqual(new List<DMProperty> {bo.Properties.CreateBusinessObject()});
            //---------------Test Result -----------------------
            Assert.IsFalse(areEqual);
        }

        [Test]
        public void Test_DMObjectIdentityAllPropsCompulsoryRule_ShouldBeOnBusinessObject()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            ReadOnlyCollection<IBusinessObjectRule> rules = BOHelper.GetBusinessObjectRules(dmObjectIdentity);
            //---------------Test Result -----------------------
            TestUtilsShared.AssertHasRuleOfType<DMObjectIdentityAllPropsCompulsoryRule>(rules);
        }

        [Test]
        public void Test_HasProperties_WhenHasOneProp_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.HasProperties;
            //---------------Test Result -----------------------
            Assert.IsTrue(hasProperties);
        }

        [Test]
        public void Test_HasProperties_WhenHasNoProps_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.HasProperties;
            //---------------Test Result -----------------------
            Assert.IsFalse(hasProperties);
        }

        [Test]
        public void Test_HasProperties_WhenHasTwoProps_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty()); 
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.HasProperties;
            //---------------Test Result -----------------------
            Assert.IsTrue(hasProperties);
        }

        [Test]
        public void Test_HasSingleProperties_WhenHasOneProp_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedDefaultDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool hasProperties = dmObjectIdentity.HasSingleProperties;
            //---------------Test Result -----------------------
            Assert.IsTrue(hasProperties);
        }

        [Test]
        public void Test_HasSingleProperties_WhenHasTwoProp_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedDefaultDMProperty());
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedDefaultDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool hasProperties = dmObjectIdentity.HasSingleProperties;
            //---------------Test Result -----------------------
            Assert.IsFalse(hasProperties);
        }

        [Test]
        public void Test_HasSingleProperties_WhenHasNoProp_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            bool hasProperties = dmObjectIdentity.HasSingleProperties;
            //---------------Test Result -----------------------
            Assert.IsFalse(hasProperties);
        }

        [Test]
        public void Test_IsComposite_WhenHasOneProp_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.IsCompositeKey;
            //---------------Test Result -----------------------
            Assert.IsFalse(hasProperties);
        }
        [Test]
        public void Test_IsCompositeWhenNoProp_ShouldRetFalse()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.IsCompositeKey;
            //---------------Test Result -----------------------
            Assert.IsFalse(hasProperties);
        }
        [Test]
        public void Test_IsCompositeWhenTwoProps_ShouldRetTrue()
        {
            //---------------Set up test pack-------------------
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity();
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty());
            dmObjectIdentity.Properties.Add(TestUtilsDMProperty.CreateUnsavedValidDMProperty());
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmObjectIdentity.Properties.Count);
            //---------------Execute Test ----------------------
            var hasProperties = dmObjectIdentity.IsCompositeKey;
            //---------------Test Result -----------------------
            Assert.IsTrue(hasProperties);
        }

        [Test]
        public void Test_IsObjectID_WhenPropertyTypeStringIsGuid_ShouldSetIsObjectIDTrue()
        {
            //---------------Set up test pack-------------------
            var dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            DMProperty property = dmObjectIdentity.Properties[0];
            property.PropertyType = new DMPropertyType("System", "Guid");
            dmObjectIdentity.Properties.Add(property);
            dmObjectIdentity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreEqual(property.PropertyTypeString, "System.Guid");
            //---------------Execute Test ----------------------
            bool? isObjectID = dmObjectIdentity.IsObjectID;
            //---------------Test Result -----------------------
            Assert.IsTrue(isObjectID.GetValueOrDefault());
        }

        [Test]
        //Bug #1022 - IsObjectID on Object Identity is getting set to false when saving
        public void Test_IsObjectID_WhenSavedPropertyIsGuid_ThenSaveAgain_ShouldStillHaveIsObjectIDTrue_BUGFIX_1022()
        {
            //---------------Set up test pack-------------------
            var dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            DMProperty property = dmObjectIdentity.Properties[0];
            property.PropertyType = new DMPropertyType("System", "Guid");
            dmObjectIdentity.Properties.Add(property);
            dmObjectIdentity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreEqual(property.PropertyTypeString, "System.Guid");
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
            //---------------Execute Test ----------------------
            dmObjectIdentity.Save();
            //---------------Test Result -----------------------
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }

        [Test]
        public void Test_IsObjectID_WhenPropertyTypeStringIsNotGuid_ShouldSetIsObjectIDFalse()
        {
            //---------------Set up test pack-------------------
            var dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = new DMPropertyType("System", "String");
            dmObjectIdentity.Properties.Add(dmProperty);
            dmObjectIdentity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreNotEqual(dmProperty.PropertyTypeString, "System.Guid");
            //---------------Execute Test ----------------------
            bool? isObjectID = dmObjectIdentity.IsObjectID;
            //---------------Test Result -----------------------
            Assert.IsFalse(isObjectID.GetValueOrDefault());
        }

        [Test]
        public void Test_SetIsObjectID_WhenPropertyTypeStringIsNotGuid_ShouldSetIsObjectIDFalse()
        {
            //---------------Set up test pack-------------------
            var dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = new DMPropertyType("System", "String");
            dmObjectIdentity.Properties.Add(dmProperty);
            dmObjectIdentity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreEqual(dmProperty.PropertyTypeString, "System.String");
            //---------------Execute Test ----------------------
            dmObjectIdentity.SetIsObjectID();
            //---------------Test Result -----------------------
            Assert.IsFalse(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }

        [Test]
        public void Test_SetIsObjectID_WhenPropertyTypeStringIsGuid_ShouldSetIsObjectIDTrue()
        {
            //---------------Set up test pack-------------------
            var dmObjectIdentity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            DMProperty dmProperty = dmObjectIdentity.Properties[0];
            dmProperty.PropertyType = new DMPropertyType("System", "Guid");
            dmObjectIdentity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmObjectIdentity.Properties.Count);
            Assert.AreEqual(dmProperty.PropertyTypeString, "System.Guid");
            //---------------Execute Test ----------------------
            dmObjectIdentity.SetIsObjectID();
            //---------------Test Result -----------------------
            Assert.IsTrue(dmObjectIdentity.IsObjectID.GetValueOrDefault());
        }

        [Test]
        public void Test_GetParent()
        {
            //---------------Set up test pack-------------------
            DMClass @class = new DMClass();
            DMObjectIdentity identity = new DMObjectIdentity();
            @class.ObjectIdentity = identity;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IModelElement parent = ((IModelElement)identity).Parent;
            //---------------Test Result -----------------------
            Assert.AreSame(@class, parent);
        }

        [Test]
        public void Test_SetParentExceptionThrown()
        {
            //---------------Set up test pack-------------------
            IModelElement identity = new DMObjectIdentity();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            Exception exceptionThrown = null;
            try
            {
                identity.Parent = new DMUniqueConstraint();
            }
            catch (Exception ex)
            {
                exceptionThrown = ex;
            }
            //---------------Test Result -----------------------
            Assert.IsNotNull(exceptionThrown);
            Assert.IsInstanceOf(typeof(HabaneroDeveloperException), exceptionThrown);
            StringAssert.Contains
                ("Set the parent of the ObjectIdentity by setting the related Class object", exceptionThrown.Message);
        }


        [Test]
        public void Test_ObjectIdentity_RemoveProperty_AddProperty_ShouldSetUpReverseRelationship()
        {
            //---------------Set up test pack-------------------
            var identity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            var dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty(identity.Class);
            identity.Properties.Add(dmProperty);
            identity.Save();
            //---------------Assert Precondition----------------
            Assert.IsTrue(identity.Properties.Contains(dmProperty));
            Assert.IsTrue(identity.Properties.PersistedBusinessObjects.Contains(dmProperty));
            Assert.IsFalse(identity.Properties.RemovedBusinessObjects.Contains(dmProperty));
            Assert.AreSame(identity, dmProperty.ObjectIdentity);
            //---------------Execute Test ----------------------
            identity.Properties.Remove(dmProperty);
            Assert.IsFalse(identity.Properties.Contains(dmProperty));
            Assert.IsTrue(identity.Properties.PersistedBusinessObjects.Contains(dmProperty));
            Assert.IsTrue(identity.Properties.RemovedBusinessObjects.Contains(dmProperty));
            Assert.IsNull(dmProperty.ObjectIdentity);
            identity.Properties.Add(dmProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(identity.Properties.Contains(dmProperty));
            Assert.IsTrue(identity.Properties.PersistedBusinessObjects.Contains(dmProperty));
            Assert.IsFalse(identity.Properties.RemovedBusinessObjects.Contains(dmProperty));
            Assert.AreSame(identity, dmProperty.ObjectIdentity);
        }

        [Test]
        public void Test_ObjectIdentity_Refresh_ShouldNotAddPersistedObjects()
        {
            //---------------Set up test pack-------------------
            var identity = TestUtilsDMObjectIdentity.CreateUnsavedValidDMObjectIdentity();
            var dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty(identity.Class);
            BusinessObjectCollection<DMProperty> properties = identity.Properties;
            properties.Add(dmProperty);
            Assert.AreEqual(0, properties.PersistedBusinessObjects.Count);
            Assert.AreEqual(2, properties.Count);
            identity.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, properties.PersistedBusinessObjects.Count);
            //---------------Execute Test ----------------------
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            identity.Properties.TimeLastLoaded = DateTime.Now.AddMilliseconds(-10000);
            identity.Properties.Refresh();
            //---------------Test Result -----------------------
            Assert.AreEqual(2, identity.Properties.PersistedBusinessObjects.Count);
        }

        private static DMObjectIdentity CreateSavedObjectIdentityInfo(DMProperty dmProperty)
        {
            DMObjectIdentity dmObjectIdentity = new DMObjectIdentity {IsObjectID = false};
            if (dmObjectIdentity.Properties.Count == 0)
            {
                dmObjectIdentity.Class = (DMClass) dmProperty.Class;
                dmProperty.ObjectIdentity = dmObjectIdentity;
            }
            dmObjectIdentity.Save();
            return dmObjectIdentity;
        }

        private static DMClass CreateBOWithIDThatHasOneProperty(out DMProperty propertyInfo2, out List<DMProperty> selectedProperties)
        {
            DMClass bo = TestUtilsShared.CreateSavedDMClass();
            TestUtilsShared.CreateSavedDMProperty(bo);
            propertyInfo2 = TestUtilsShared.CreateSavedDMProperty(bo);
            TestUtilsShared.CreateSavedDMProperty(bo);
            selectedProperties = new List<DMProperty> {propertyInfo2};

            bo.SetObjectIdentity(selectedProperties);
            return bo;
        }
        // ReSharper restore InconsistentNaming
    }
}
